package com.suxin.nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Tang
 * @classname ServerNio_1
 * @description [  ]
 * @date 2021/6/9 15:39
 */
public class ServerNio_2 {

    public static void main(String[] args) throws Exception {
        ServerSocketChannel socketChannel = ServerSocketChannel.open();
        socketChannel.configureBlocking(false);
        socketChannel.bind(new InetSocketAddress("127.0.0.1", 9999), 1024);

        Selector selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_ACCEPT);

        ByteBuffer allocate = ByteBuffer.allocate(1024);

        System.out.println("服务器启动监听...");
        while (true) {
            while (selector.select() > 0) {
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    if (selectionKey.isAcceptable()) {
                        SocketChannel channel = socketChannel.accept();
                        channel.configureBlocking(false);
                        channel.register(selector, SelectionKey.OP_READ);
                        System.out.println("接收到了新的客户端连接: " + channel.hashCode());
                    }
                    if (selectionKey.isReadable() || selectionKey.isWritable()) {
                        SelectableChannel selectableChannel = selectionKey.channel();
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
                        if (selectionKey.isReadable()) {
                            allocate.clear();
                            allocate.rewind();
                            int read = channel.read(allocate);
                            allocate.position(0);
                            allocate.limit(read);
                            byte[] bt = new byte[1024];
                            allocate.get(bt, 0, read);
                            String msg = new String(bt, 0, read);
                            System.out.println("读取收到数据为: " + msg);
                            if ("R".equals(msg)) {
                                System.out.println("改变为写事件...");
                                selectionKey.interestOps(selectionKey.interestOps() | SelectionKey.OP_WRITE);
                            }
                        }
                        if (selectionKey.isWritable()) {
                            channel.write(ByteBuffer.wrap("receive!".getBytes()));
                            System.out.println("服务器数据发送成功!");
                            selectionKey.interestOps(SelectionKey.OP_READ);
                            // 唤醒阻塞
                            selector.wakeup();
                        }
                    }
                }
                iterator.remove();
            }
        }
    }
}